<?php

namespace common\service\step_category_month_report;

use common\model\EpisodeStepCategorySealTimeModel;
use common\model\PlanModel;

/**
 * 剧集待办统计
 *  待办没有返修、工单
 *  通过率必定是100%
 *  工单问题占比必定是0%
 */
class EpisodeReportCount extends EpisodeReportCountBase
{

    protected $planDonePlanData = [];

    public function getPlanDonePlanData($projectId, $monthStart, $monthEnd, $stepCategoryIdList)
    {
        if (!empty($this->planDonePlanData)) {
            return $this->planDonePlanData;
        }
        $this->planDonePlanData = model(PlanModel::class)
            ->alias('p')
            ->join('task_relation_tag r_step_category on p.task_id = r_step_category.task_id')
            ->where(['p.project_id' => $projectId])
            ->where(['p.type' => PlanModel::TYPE_STEP_CATEGORY, 'p.scope' => PlanModel::SCOPE_SINGLE])
            ->where([['p.end_time' => ['EGT', $monthStart]], ['p.end_time' => ['ELT', $monthEnd]]])
            ->where(['r_step_category.link_module_code' => ['IN', ['step_category', 'show_step_category']]])
            ->where(['r_step_category.link_id' => ['IN', implode(',', $stepCategoryIdList)]])
            ->field('p.*')
            ->cache(APP_DEBUG ? false : C('database.default_query_cache_time'))
            ->select();
        return $this->planDonePlanData;
    }

    /**
     * 计算统计数据
     * @param $projectId
     * @param $stepCategoryIdList
     * @param $monthStart
     * @param null $monthEnd
     * @return void
     */
    public function calculate($projectId, $stepCategoryIdList, $monthStart, $monthEnd = null)
    {
        $this->countObject = new StepCategoryMonthCountObject();
        $monthStart = strtotime($monthStart);
        if (empty($monthEnd)) {
            $monthEnd = strtotime("+1 month -1 second", $monthStart);
        } else {
            $monthEnd = strtotime($monthEnd);
            $this->countObject->canBeSaved = false;
        }
        $planData = $this->getPlanDonePlanData($projectId, $monthStart, $monthEnd, $stepCategoryIdList);
        $planDataGroupByEpisode = array_group_by($planData, 'entity_id');
        $planEpisode = count($planDataGroupByEpisode);
        $this->countObject->deliveryUnit = '集';
        $this->countObject->projectId = $projectId;
        $this->countObject->tenantId = request()->getTenantId();
        $this->countObject->monthTime = $monthStart;
        $this->countObject->stepCategoryIds = implode(',', $stepCategoryIdList);

        $this->countObject->planDelivery = $planEpisode;
        $this->countObject->shouldDelivery = $planEpisode;
        $this->countObject->addDelivery = 0;
        $this->countObject->passPercent = 1;
        $this->countObject->taskWorkOrderPercent = 0;
        $this->countObject->havePlan = !empty($planData);
        if ($planEpisode > 0) {
            $episodeIdList = array_column($planData, 'entity_id', 'entity_id');
            $episodePlanEndTime = array_column($planData, 'end_time', 'entity_id');
            $episodeStepCategorySealTimeList = model(EpisodeStepCategorySealTimeModel::class)
                ->where([
                    [
                        'entity_id' => ['IN', implode(',', $episodeIdList)],
                        'seal_time' => ['BETWEEN', [$monthStart, $monthEnd]],
                        '_logic' => 'OR',
                    ]
                ])
                ->where(["project_id" => $projectId])
                ->where("FIND_IN_SET(" . $stepCategoryIdList[0] . ",step_category_ids) and seal_time > 0 ")
                ->group('entity_id')
                ->select();

            foreach ($episodeStepCategorySealTimeList as $episodeStepCategorySealTimeItem) {
                $planEndTime = $episodePlanEndTime[$episodeStepCategorySealTimeItem['entity_id']] ?? 0;

                if ($episodeStepCategorySealTimeItem['seal_time'] >= 0 && $episodeStepCategorySealTimeItem['seal_time'] <= $monthEnd && $episodeStepCategorySealTimeItem['seal_time'] >= $monthStart) {
                    // 在统计周期内已经完成
                    $this->countObject->delivery += 1;
                }
                if (in_array($episodeStepCategorySealTimeItem['entity_id'], $episodeIdList) && $planEndTime > 0) {
                    // 计划交付是否异常 (到期没有交付/或逾期交付)
                    if (
                        $episodeStepCategorySealTimeItem['seal_time'] > $planEndTime
                        || ($episodeStepCategorySealTimeItem['seal_time'] == 0 && $planEndTime <= time())
                    ) {
                        $this->countObject->abnormal += 1;
                    }
                }
            }
        }
        // 交付率
        $this->setDeliveryPercent();
        $this->setIsPlanDone();
        $this->saveCountObjectData();
    }
}
